<!DOCTYPE html>
<html>
<head>
<title>Snake</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="css/snake.css" rel="stylesheet" type="text/css">
<link href="../js/css.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="../js/popup.js"></script>
<script type="text/javascript">
	var $ = function(id) {
		return document.getElementById(id);
	}
	
	Array.prototype.forEach = function(iterator) {
		for (var i = 0; i < this.length; i++) {
			iterator(this[i]);
		}
	}
</script>
<script type="text/javascript">
	var SIZE;
	var PANEL_WIDTH;
	var PANEL_HEIGHT;
	function set()
	{
		SIZE = 20;
		var panel = $('panel');
		PANEL_WIDTH = panel.clientWidth/SIZE;
		PANEL_HEIGHT = panel.clientHeight/SIZE;
	}
//-----------Food--------------------------------------------------
	var Food=function(x,y,panel) {
		var body=document.createElement("div");
		body.className="food";
		this.div=body;
		this.xPos=x;
		this.yPos=y;
		panel.appendChild(body);
	}
	
	Food.prototype.setPosition=function(x,y) {
		this.xPos=x;
		this.yPos=y;
	}
	
	Food.prototype.draw=function() {
		this.div.style.left=this.xPos*SIZE + "px";
		this.div.style.top=this.yPos*SIZE + "px";
	}
	
	Food.prototype.remove=function() {
		document.all.panel.removeChild(this.div);
	}
//------------Body-----------------------------------------------------
	var Body=function(x,y) {
		var div=document.createElement("div");
		div.className="snake";
		this.view=div;
		this.xPos=x;
		this.yPos=y;
	}
	Body.prototype.move = function(x,y) {
		this.xPos=x;
		this.yPos=y;
	}
	Body.prototype.getPosition = function() {
		return {x:this.xPos, y:this.yPos};
	}
	Body.prototype.updateView = function() {
		this.view.style.left = this.xPos*SIZE + "px";
		this.view.style.top = this.yPos*SIZE + "px";
	}
//-------------Snake----------------------------------------------------	
	var Snake=function(x,y,length,panel) {
		this.bodys=new Array();
		this.movX=0;
		this.movY=0;
		this.moving=false;
		this.panel=panel;
		this.initialize(x,y,length);
	}
	Snake.prototype={			
		initialize: function(x,y,length){
			for(var i=0;i<length;i++) {
				this.addBody(new Body(x,y));
			}
			this.moving = true;
		},
		
		move: function(food){
			if(this.moving == false) {
				return false;
			}
			var arr=this.bodys;
			
			var head=arr[0];
			var hpos=head.getPosition();
			
			var toX=hpos.x+this.movX;
			var toY=hpos.y+this.movY;
			if(this.die(toX,toY)) {
				return false;
			}

			head.move(toX,toY);
			var returnValue = false;
			if(head.xPos==food.xPos&&head.yPos==food.yPos) {
				this.eat(food);
				returnValue = true;
			}
			var toPos=hpos;
			for(var i=1;i<arr.length;i++) {
				var pos=arr[i].getPosition();
				arr[i].move(toPos.x,toPos.y);
				toPos=pos;
			}
			return returnValue;
		},
		updateView: function(){
			this.bodys.forEach(function(b){
				b.updateView();
			})
		},
		eat: function(food){
			var x=food.xPos;
			var y=food.yPos;
			this.addBody(new Body(x,y));
		},
		addBody: function(body){
			this.panel.appendChild(body.view);
			this.bodys.push(body);
		},
		die: function(x,y){
			var bdie=(x<0||y<0||x>=PANEL_WIDTH||y>=PANEL_HEIGHT);
			if(bdie==true)
			{
				this.movX=0;
				this.movY=0;
				this.moving=false;
			}
			return bdie;
		}
	}
//-----------------------------------------------------------------
	var Game = function(panel) {
		this.panel = panel;
		this.snake = null;
		this.food = null;
		this.isStarted = false;
		this.warnUI = null;
		this.initialize();
	}

	Game.prototype = {
		initialize: function() {
			this.snake = new Snake(10, 10, 3, this.panel);
			this.initKeyboard();
			if (navigator.userAgent.indexOf('Mobile') > -1) {
				this.initTouchMotion();
			}
		},
		
		start: function() {
			this.isStarted = true;
			this.addFood();
			this.run();
		},
		
		run: function() {
			if (this.snake.move(this.food)) {
				this.addFood();
			}
			this.snake.updateView();
			
			if (this.snake.moving == false) {
				this.gameOver();
				return;
			} else {
				var _game = this;
				setTimeout(function() {
					_game.run();
				}, 100);
			}
		},
		
		restart: function() {
			var childNodes = this.panel.childNodes;
			for (var i = childNodes.length - 1; i >= 0; i--) {
				this.panel.removeChild(childNodes[i]);
			}
			this.snake = new Snake(10, 10, 3, this.panel);
			this.food = null;
			this.start();
		},
		
		initKeyboard: function() {
			var _game = this;
			document.onkeydown = function(e) {
				if(_game.snake.moving == false) {
					return;
				}
				var event = e || window.event;
				var val = '';
				switch(event.keyCode) {
					case 37: val = 'left'; break;
					case 38: val = 'up'; break;
					case 39: val = 'right'; break;
					case 40: val = 'down'; break;
				}
				if (val != '') {
					_game.control(val);
				}
			}
		},
		
		initTouchMotion: function() {
			var _game = this;
			var addListener = document.addEventListener || document.attachEvent;
			addListener.call(document, "touchstart", function(event) {
				if (!_game.isStarted) {
					return;
				}
				event.preventDefault();
				var touchEvent = event.targetTouches[0];
				this.startX = touchEvent.pageX;
				this.startY = touchEvent.pageY;
			}, false);
			
			addListener.call(document, "touchmove", function(event) {
				if (!_game.isStarted) {
					return;
				}
				event.preventDefault();
				var touchEvent = event.targetTouches[0];
				var posX = touchEvent.pageX;
				var posY = touchEvent.pageY;
				var _x = posX - this.startX;
				var _y = posY - this.startY;
				
				var direct = '';
				if (Math.abs(_x) >= Math.abs(_y)) {
					if (_x > 0) {
						direct = 'right';
					} else if (_x < 0) {
						direct = 'left';
					}
				} else {
					if (_y > 0) {
						direct = 'down';
					} else if (_y < 0) {
						direct = 'up';
					}
				}
				_game.control(direct);
				
			}, false);
		},
		
		control: function(val) {
			if(this.snake.moving == false) {
				return;
			}
			if(val == 'left') {
				if(this.snake.movX == 1) {
					return;
				}
				this.snake.movX = -1;
				this.snake.movY = 0;
			} else if(val == 'up') {
				if(this.snake.movY == 1) {
					return;
				}
				this.snake.movX = 0;
				this.snake.movY = -1;
			} else if(val == 'right') {
				if(this.snake.movX == -1) {
					return;
				}
				this.snake.movX = 1;
				this.snake.movY = 0;
			} else if(val == 'down') {
				if(this.snake.movY == -1) {
					return;
				}
				this.snake.movX = 0;
				this.snake.movY = 1;
			}
		},
		
		gameOver: function() {
			this.isStarted = false;
			var _game = this;
			var dialog = Popup.newDialog('GAMER OVER');
			dialog.addButton({
				value: 'Restart',
				action: function() {
					_game.restart();
				}
			});
			dialog.show();
		},
		
		addFood: function() {
			var x = parseInt(Math.random() * PANEL_WIDTH);
			var y = parseInt(Math.random() * PANEL_HEIGHT);
			if(this.food == null) {
				this.food = new Food(x, y, this.panel);
			} else {
				this.food.setPosition(x, y);
			}
			this.food.draw();
		}
	}

	window.onload=function(){
		set();
		var game = new Game($('panel'));
		game.start();
	}
	
</script>
</head>
<body>
	<div class='panel' id='panel'></div>
</body>
</html>